// echo aux function only, should not compile alone.
// -r:"../../Backend/System.IO.FileSystem.dll"

//! 编译方法，目前来说只能是自己改上面那行字，把缺的东西都补齐，之后送命令提示符或者用python脚本编译。
//! windows就是一坨shit……连通配符都不支持……不然我至少能写出类似 dotnet C:\Program Files\dotnet\sdk\*\Roslyn\bincore\csc.dll 这样的语法

// -r:"../../The Scroll of Taiwu_Data/Managed/Mono.Cecil.dll" -r:"../../The Scroll of Taiwu_Data/Managed/System.Core.dll"   -r:"../../The Scroll of Taiwu_Data/Managed/System.Composition.AttributedModel.dll" -r:"../../Backend/System.Runtime.dll"
/**
 *  Everyone's Unity Game Plugin
 *  Copyright (C) 2022 Neutron3529
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Affero General Public License as
 *  published by the Free Software Foundation, either version 3 of the
 *  License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Affero General Public License for more details.
 *
 *  You should have received a copy of the GNU Affero General Public License
 *  along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */
//! 这是一个自带文档注释的Mod，虽然代码很shit，但里面有不少注释，或许会对之后准备玩过月逻辑的人有帮助。
//! 所有文档注释会用//!开头，请注意搜索
//! 首先是前后端，前端对后端的调用会先被塞进 ProcessMethodCall，之后分发给对应domain的CallMethod，由CallMethod进行进一步的分发。借助这一点，我们可以快速找到前端调用究竟是在使用哪个函数。
using System;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Collections.Generic;
using static Utils.Logger;

using Config.EventConfig;
using GameData.Domains.TaiwuEvent;
using GameData.Domains.TaiwuEvent.Enum;

namespace Neutron3529.ChaosEvents {
    public partial class ChaosEvents : EventPackage {
        public 王公.王公 E09(){
            var o=new 王公.王公();
            {
                var taiwuEvent = GameData.Domains.DomainManager.TaiwuEvent.GetEvent("fb38f657-6ed0-41e4-a0c2-c82afb49762f"); // @人物互动-恩义互动
                var lst=taiwuEvent.EventConfig.EventOptions.ToList();
                for(int i=0;i<o.EventOptions.Length-1/*其他话题*/;i++){
                    lst.Insert(lst.Count-1, o.EventOptions[i]);
                }
                taiwuEvent.EventConfig.EventOptions=lst.ToArray();
            }
            return o;
        }
    }
    namespace 王公 {
        public class 王公 : EventItem {
            public static sbyte DefKey_MakeLove=typeof(Config.PersonalNeed.DefKey).GetField("MakeLove",(BindingFlags)(-1))==null?Config.PersonalNeed.DefKey.MakeLove:(sbyte)typeof(Config.PersonalNeed.DefKey).GetField("MakeLove",(BindingFlags)(-1)).GetValue(null);
            public static short DefKey_VirginityTrue = typeof(Config.CharacterFeature.DefKey).GetField("VirginityTrue",(BindingFlags)(-1))==null?Config.CharacterFeature.DefKey.VirginityTrue:(short)typeof(Config.CharacterFeature.DefKey).GetField("VirginityTrue",(BindingFlags)(-1)).GetValue(null);
            public static short DefKey_VirginityFalse = typeof(Config.CharacterFeature.DefKey).GetField("VirginityFalse",(BindingFlags)(-1))==null?Config.CharacterFeature.DefKey.VirginityFalse:(short)typeof(Config.CharacterFeature.DefKey).GetField("VirginityFalse",(BindingFlags)(-1)).GetValue(null);
            public static short DefKey_Pregnant = typeof(Config.CharacterFeature.DefKey).GetField("Pregnant",(BindingFlags)(-1))==null?Config.CharacterFeature.DefKey.Pregnant:(short)typeof(Config.CharacterFeature.DefKey).GetField("Pregnant",(BindingFlags)(-1)).GetValue(null);
            public static ushort RelationType_HusbandOrWife=((ushort?)(typeof(GameData.Domains.Character.Relation.RelationType).GetField("HusbandOrWife",(BindingFlags)(-1))?.GetValue(null)))??GameData.Domains.Character.Relation.RelationType.HusbandOrWife;
            public 王公() :base("Prof.王公", "70b4d45d-ba15-423d-b94e-b40e348eb9c9", "“这位<Character key=CharacterId str=AutoAgeGender/>，要不要体验一下怀孕生子，以感受母爱的伟大呢？\n<Character key=CharacterId str=Name/>听得<Character key=RoleTaiwu str=Name/>之言，颇有些意动\n\n<color=#lightgrey>（帮助<Character key=CharacterId str=Name/>找到需要代孕孩子的准妈妈）</color>"){
                this.EventOptions = new TaiwuEventOption[2];//（介绍代孕……）/（便是此人了……） （其他话题……）
                for(int i=0;i<this.EventOptions.Length;i++){
                    var op=new TaiwuEventOption {
                        OptionKey = "Option_352909"+(i+1).ToString("02"),
                        OnOptionSelect = new Func<string>(this.OnOptionSelect(i)),
                        OnOptionVisibleCheck = new Func<bool>(this.OnCheckOptionCondition(i)),
                        OnOptionAvailableCheck = new Func<bool>(this.OnCheckEventCondition),
                        GetReplacedContent = new Func<string>(this.Desc(i)),
                        GetExtraFormatLanguageKeys = new Func<List<string>>(this.GetExtraFormatLanguageKeys)
                    };
                    this.EventOptions[i]=op;
                }
            }
            // public override string EventContent()=>string.Format(this.content, Name(this.ArgBox.GetCharacter("CharacterId")), Name(GameData.Domains.DomainManager.Taiwu.GetTaiwu()));
            private Func<bool> OnCheckOptionCondition(int index){
                switch(index){
                    default: return ()=>{
                        var pd=GameData.Domains.TaiwuEvent.EventHelper.EventHelper.GetCurrentProfessionData();
                        var character=this.EventOptions[index].ArgBox.GetCharacter("CharacterId");
                        if(pd!=null && AddElement_PregnantStates!=null && RemoveElement_PregnantStates!=null && pd.TemplateId == 17 && character!=null && (!character.GetFeatureIds().Contains(DefKey_Pregnant)) && character.GetLocation().IsValid() && character.GetGender()==0){
                            var blck=GameData.Domains.DomainManager.Map.GetBlock(character.GetLocation());
                            if(blck!=null && blck.CharacterSet!=null){
                                var CharacterSet=blck.CharacterSet.Union(GameData.Domains.DomainManager.Taiwu.GetGroupCharIds().GetCollection());
                                return CharacterSet.Count((x)=>GameData.Domains.DomainManager.Character.TryGetElement_Objects(x, out character) && GameData.Domains.DomainManager.Character.TryGetPregnantState(character.GetId(), out var _) && !GameData.Domains.DomainManager.Building.TryGetElement_SamsaraPlatformBornDict(character.GetId(),out var _))>0;
                            }
                        }
                        return false;
                    };
                }
            }
            public override void OnEventEnter(){
                var character=this.ArgBox.GetCharacter("CharacterId");
                var blck=GameData.Domains.DomainManager.Map.GetBlock(character.GetLocation());
                var lst=new List<int>();
                var tmp=character;
                if(blck!=null && blck.CharacterSet!=null){
                    var CharacterSet=blck.CharacterSet.Union(GameData.Domains.DomainManager.Taiwu.GetGroupCharIds().GetCollection());
                    foreach(var x in CharacterSet){
                        if(GameData.Domains.DomainManager.Character.TryGetElement_Objects(x, out character) && GameData.Domains.DomainManager.Character.TryGetPregnantState(character.GetId(), out var _) && !GameData.Domains.DomainManager.Building.TryGetElement_SamsaraPlatformBornDict(character.GetId(),out var _)){
                            lst.Add(x);
                        }
                    }
                }
                // var lst=(from x in GameData.Domains.DomainManager.Map.GetBlock(character.GetLocation()).CharacterSet where x!=character.GetId() select x).ToList();
                GameData.Domains.TaiwuEvent.EventHelper.EventHelper.SelectCharacterFromCharIdList(this.ArgBox, "CharacterId2", lst);
            }
            MethodInfo AddElement_PregnantStates=typeof(GameData.Domains.Character.CharacterDomain).GetMethod("AddElement_PregnantStates",(BindingFlags)(-1));
            MethodInfo RemoveElement_PregnantStates=typeof(GameData.Domains.Character.CharacterDomain).GetMethod("RemoveElement_PregnantStates",(BindingFlags)(-1));
            private unsafe Func<string> OnOptionSelect(int index){
                switch(index){
                    case 0:return ()=>{
                        if(this.EventOptions[index].ArgBox.Contains<bool>("NeutronFlag")){//重入branch
                            this.ArgBox.Remove<bool>("NeutronFlag");
                            var character=this.ArgBox.GetCharacter("CharacterId");
                            var cname=Name(character);
                            var tname=Name(GameData.Domains.DomainManager.Taiwu.GetTaiwu());
                            var c2=this.ArgBox.GetCharacter("CharacterId2");
                            this.ArgBox.Remove<int>("CharacterId2");
                            var c2n=Name(c2);
                            var currDate=GameData.Domains.DomainManager.World.GetCurrDate();
                            var location=character.GetLocation();
                            var lifeRecordCollection = GameData.Domains.DomainManager.LifeRecord.GetLifeRecordCollection();

                            c2.AddFeature(this.context,DefKey_VirginityTrue,true);
                            c2.RemoveFeature(this.context,DefKey_Pregnant);
                            character.AddFeature(this.context,DefKey_Pregnant,true);
                            GameData.Domains.DomainManager.Character.RemovePregnantLock(context, character.GetId());
                            AddElement_PregnantStates.Invoke(GameData.Domains.DomainManager.Character,new object[]{character.GetId(), GameData.Domains.DomainManager.Character.GetPregnantState(c2.GetId()), this.context});
                            RemoveElement_PregnantStates.Invoke(GameData.Domains.DomainManager.Character, new object[]{c2.GetId(), this.context});

                            if(character.HasVirginity()){
                                character.LoseVirginity(this.context);
                                return Goto($"“唔，有人想要孩子，有人却不想要孩子，这个世界真的很奇怪啊。”\n{cname}只见{c2n}一副对自己孩子毫不在乎甚至有些如释重负的神情\n心头的十分欣喜不知为什么弱了几分。\n\n<color=#lightgrey>（{c2n}腹中胎儿被安全地转移到了{cname}腹中）\n（{tname}依照约定，将{cname}体内的元阴转移给了{c2n}）</color>","（如此甚好……）",index);
                            } else {
                                var pnl=c2.GetPersonalNeeds();
                                var blck=GameData.Domains.DomainManager.Map.GetBlock(character.GetLocation());
                                var tmp=character;
                                int snake=0;
                                if(blck!=null && blck.CharacterSet!=null){
                                    var CharacterSet=blck.CharacterSet.Union(GameData.Domains.DomainManager.Taiwu.GetGroupCharIds().GetCollection());
                                    foreach(var x in CharacterSet){
                                        if(GameData.Domains.DomainManager.Character.TryGetElement_Objects(x, out tmp) && tmp.GetGender()!=0){
                                            for(int i=0;i<10;i++){
                                                pnl.Add(GameData.Domains.Character.Ai.PersonalNeed.CreatePersonalNeed(DefKey_MakeLove, x));
                                            }
                                            snake++;
                                        }
                                    }
                                }
                                if(snake==0){
                                    snake++;
                                    foreach(var cid in GameData.Domains.TaiwuEvent.EventHelper.EventHelper.GetRelatedCharacters(c2.GetId(), RelationType_HusbandOrWife,true)){
                                        for(int i=0;i<10;i++){
                                            pnl.Add(GameData.Domains.Character.Ai.PersonalNeed.CreatePersonalNeed(DefKey_MakeLove, cid));
                                        }
                                        snake++;
                                    }
                                }
                                c2.SetPersonalNeeds(pnl,context);
                                GameData.Domains.TaiwuEvent.EventHelper.EventHelper.ShowGetItemPageForItems(new List<(GameData.Domains.Item.ItemKey,int)>(){(GameData.Domains.TaiwuEvent.EventHelper.EventHelper.AddItemToRole(GameData.Domains.DomainManager.Taiwu.GetTaiwu(), 5, 66, snake),snake)},Goto($"“唔，有人想要孩子，有人却不想要孩子，这个世界真的很奇怪啊。”\n{cname}只见{c2n}一副对自己孩子毫不在乎甚至有些如释重负的神情\n心头的十分欣喜不知为什么弱了几分。\n\n<color=#lightgrey>（{c2n}腹中胎儿被安全地转移到了{cname}腹中）\n<s>（{tname}本想依照约定，将{cname}体内的元阴转移给{c2n}，但上手时发现{cname}的元阴早就泄干净了）\n（{cname}不住央求，并找来几条<color=#GradeColor_3>百花锦蛇</color>，表示它们的元阴也是元阴）\n（想到这一幕，{tname}不由得握紧了手中那条已经被榨成蛇干的<color=#GradeColor_3>百花锦蛇</color>）</s></color>","（如此甚好……）",index),this.EventOptions[index].ArgBox);
                                return string.Empty;
                            }
                        } else {//初入branch
                            this.EventOptions[index].ArgBox.Set("NeutronFlag",false);
                            return this.guid;//重入
                        }
                    };
                    case 1:return ()=>{
                        this.EventOptions[index].ArgBox.Remove<bool>("NeutronFlag");
                        return "fb38f657-6ed0-41e4-a0c2-c82afb49762f"; // @人物互动-恩义互动
                    };
                    default: return ()=>string.Empty;
                }
            }
            public override Func<string> Desc(int index){
                switch(index){
                    case 0:
                        return ()=>{
                            return this.EventOptions[index].ArgBox.Contains<bool>("NeutronFlag")?"（便是此人了……）":"（介绍代孕……）";
                        };
                    case 1:
                        return ()=>{
                            return "（其他话题……）";
                        };
                    default: return ()=>string.Empty;
                }
            }
        }
    }
}
